package org.jeecg.modules.xxgx.djgl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.xxgx.common.service.IXxBase;
import org.jeecg.modules.common.util.StringUtilsExt;
import org.jeecg.modules.common.util.Convert;
import org.jeecg.modules.xxgx.common.util.BarCodeUtils;
import org.jeecg.modules.xxgx.common.util.FPUtil;
import org.jeecg.modules.xxgx.common.util.InvoiceCalcUtil;
import org.jeecg.modules.xxgx.djgl.constant.NumberConstant;
import org.jeecg.modules.xxgx.djgl.constant.StringConstant;
import org.jeecg.modules.xxgx.djgl.dto.DjcfDto;
import org.jeecg.modules.xxgx.djgl.dto.IntelligentCodingDto;
import org.jeecg.modules.xxgx.djgl.dto.IntelligentCodingMainDto;
import org.jeecg.modules.xxgx.djgl.entity.*;
import org.jeecg.modules.xxgx.djgl.service.*;
import org.jeecg.modules.xxgx.djgl.vo.IntelligentCodingVo;
import org.jeecg.modules.xxgx.djgl.vo.PreviewQRcodeVo;
import org.jeecg.modules.xxgx.spgl.entity.CsXxProduct;
import org.jeecg.modules.xxgx.spgl.service.ICsXxProductService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class DjclImpl implements IDjcl {


    @Autowired
    private ICsXxDkdjService iCsXxDkdjService;

    @Autowired
    private ICsXxDkdjmxService iCsXxDkdjmxService;

    @Autowired
    private ICsXxDjclService iCsXxDjclService;

    @Autowired
    private ICsXxDjclmxService iCsXxDjclmxService;

    @Autowired
    private ICsXxProductService iCsXxProductService;

    @Autowired
    private IXxBase xxBase;
    @Autowired
    private ISysDictService sysDictService;

    @Override
    public Result<String> orderCombineNoDetailCombineById(String ids) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        Integer tenant_id = user.getLoginTenantId();
        String company_id = user.getCompanyId();
        String sys_org_code = user.getOrgCode();
        if (StringUtils.isEmpty(ids)) {
            throw new JeecgBootException("单据合并，参数不能为空！");
        }
        //合并后新生成的ID列表
        List<String> newidList = new ArrayList<>();
        List<String> idList = Arrays.asList(ids.split(","));

        //只有一个单据合并时，直接返回，不处理
        if (idList.size() == 1) {
            newidList.add(ids);
            return null;
        }
        //查询出选择单据的数据
        LambdaQueryWrapper<CsXxDkdj> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CsXxDkdj::getId, idList);
        List<CsXxDkdj> csXxDkdjlist = iCsXxDkdjService.list(wrapper);
        //过虑出已开票、开票中的单据
        List<CsXxDkdj> filterList = csXxDkdjlist.stream().filter(item -> StringConstant.STR_1.equals(item.getKpzt()) || StringConstant.STR_3.equals(item.getKpzt())).collect(Collectors.toList());
        //开票中、已开票的单据不处理
        if (!filterList.isEmpty()) {
            throw new JeecgBootException("选择的单据包括开票中、已开票的单据");
        }

        List<CsXxDkdj> filterList2 = csXxDkdjlist.stream().filter(item -> "1".equals(item.getClfs())).collect(Collectors.toList());
        if (!filterList2.isEmpty()) {
            throw new JeecgBootException("选择的单据包括已经合并过的单据");
        }

        Map<String, List<CsXxDkdj>> fplxdmMap = csXxDkdjlist.stream().collect(Collectors.groupingBy(CsXxDkdj::getFplxdm));

        try {
            //按票种单据合并
            fplxdmMap.forEach((key, valueList) -> {
                //按客户名称分组
                Map<String, List<CsXxDkdj>> collect = valueList.stream().collect(Collectors.groupingBy(CsXxDkdj::getKhmc));
                //相同客户的单据合并成一个单据
                collect.forEach((clientNameGroup, groupDataList) -> {
                    //得到相同客户 所有ywdjbh
                    String newywdjbh = this.getAllYwdjbh(groupDataList);
                    //相关客户合并前的单据ID
                    List<String> oldOrderIdList = new ArrayList<>();
                    //复制第一个单据为新对象
                    CsXxDkdj newOrder = this.copyNewOrder(groupDataList.get(0));
                    //新单据ID
                    String newId = newOrder.getId();
                    newidList.add(newId);
                    //生成新的ywdjbh
                    //20231018 yangzheng 改为不重新生成ywdjbh 用原先业务单据编号 的逗号分割
                    //String newYwdjbh = IdWorker.getIdStr();
                    newOrder.setYwdjbh(newywdjbh);
                    //合计金额（不含税金额）
                    BigDecimal hjjeTotal = BigDecimal.ZERO;
                    //合计税额 (税额)
                    BigDecimal hjseTotal = BigDecimal.ZERO;
                    Map<String, String> bzMap = Maps.newHashMap();
                    List<String> bzList = new ArrayList<>();

                    //金额汇总、备注合并
                    for (CsXxDkdj item : groupDataList) {
                        //暂存处理前的原申请单ID
                        oldOrderIdList.add(item.getId());
                        hjjeTotal = hjjeTotal.add(item.getHjje());
                        hjseTotal = hjseTotal.add(item.getHjse());
                        //合并备注
                        if (StringUtils.isNotEmpty(item.getBz())) {
                            bzMap.put(item.getBz(), item.getBz());
                        }
                    }
                    bzMap.forEach((keyName, value) -> {
                        bzList.add(value);
                    });
                    newOrder.setHjje(hjjeTotal);
                    newOrder.setHjse(hjseTotal);
                    //根据金额修改单据的开票类型，如果金额大于0默认为蓝票
                    if (hjjeTotal.compareTo(BigDecimal.ZERO) >= 0) {
                        newOrder.setKplx(StringConstant.STR_0);
                    } else {
                        newOrder.setKplx(StringConstant.STR_1);
                    }

                    //备注以","分隔合并
                    String bzStr = Joiner.on(",").join(bzList);
                    if (bzStr.length() >= 240) {
                        bzStr = bzStr.substring(0, 241);
                    }
                    newOrder.setBz(Joiner.on(",").join(bzList));

                    //更新原来主表的单据状态为无效
                    LambdaUpdateWrapper<CsXxDkdj> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.in(CsXxDkdj::getId, oldOrderIdList);
                    updateWrapper.set(CsXxDkdj::getDjzt, "1");
                    updateWrapper.set(CsXxDkdj::getClfs, "3");//设置原先的单据为被合并单据
                    iCsXxDkdjService.update(updateWrapper);

                    //插入新的主表单据
                    iCsXxDkdjService.save(newOrder);

                    //单据处理表 数据保存
                    String djclId = IdWorker.getIdStr();
                    CsXxDjclDo csXxDjclDo = new CsXxDjclDo();
                    csXxDjclDo.setId(djclId);
                    csXxDjclDo.setTenantId(tenant_id);
                    csXxDjclDo.setCompanyId(company_id);
                    csXxDjclDo.setSysOrgCode(sys_org_code);
                    csXxDjclDo.setCllx("1");
                    csXxDjclDo.setHblx("dj");
                    iCsXxDjclService.save(csXxDjclDo);

                    //找到合并前的所有单据明细
                    //插入合并后的单据明细
                    LambdaQueryWrapper<CsXxDkdjmx> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.in(CsXxDkdjmx::getFromid, oldOrderIdList);
                    List<CsXxDkdjmx> csXxDkdjmxList = iCsXxDkdjmxService.list(queryWrapper);
                    for (CsXxDkdjmx csXxDkdjmx : csXxDkdjmxList) {
                        String oldMxid = csXxDkdjmx.getId();
                        String newMxid = IdWorker.getIdStr();
                        csXxDkdjmx.setId(newMxid);
                        csXxDkdjmx.setFromid(newId);
                        csXxDkdjmx.setYwdjbh(newOrder.getYwdjbh());
                        iCsXxDkdjmxService.save(csXxDkdjmx);


                        //单据处理明细表处理
                        CsXxDjclmxDo csXxDjclmxDo = new CsXxDjclmxDo();
                        csXxDjclmxDo.setId(IdWorker.getIdStr());
                        csXxDjclmxDo.setCompanyId(company_id);
                        csXxDjclmxDo.setTenantId(tenant_id);
                        csXxDjclmxDo.setSysOrgCode(sys_org_code);
                        csXxDjclmxDo.setFromid(djclId);
                        csXxDjclmxDo.setYdjzj(oldMxid);
                        csXxDjclmxDo.setXdjzj(newMxid);
                        iCsXxDjclmxService.save(csXxDjclmxDo);
                    }
                });
            });
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }
        return null;
    }

    private CsXxDkdj copyNewOrder(CsXxDkdj oldCsXxDkdj) {
        CsXxDkdj newCsXxDkdj = new CsXxDkdj();
        //复制当前单据的主表数据
        BeanUtil.copyProperties(oldCsXxDkdj, newCsXxDkdj);
        //新单据ID
        newCsXxDkdj.setId(IdWorker.getIdStr());
        //标记为不是原始单据 0是原单  1是合并处理  2是拆分处理
        newCsXxDkdj.setClfs("1");
        //单据状态为有效
        newCsXxDkdj.setDjzt("0");
        newCsXxDkdj.setDjrq(new Date());
        return newCsXxDkdj;
    }

    private String getAllYwdjbh(List<CsXxDkdj> list) {
        return list.stream().map(CsXxDkdj::getYwdjbh).collect(Collectors.joining(","));
    }

    private CsXxDkdjAndMx copyNewOrder(CsXxDkdjAndMx old, String clfs) {
        CsXxDkdjAndMx csXxDkdjAndMx = new CsXxDkdjAndMx();
        //复制当前单据的主表数据
        BeanUtil.copyProperties(old, csXxDkdjAndMx);
        csXxDkdjAndMx.setId(IdWorker.getIdStr());
        csXxDkdjAndMx.setClfs(clfs);
        csXxDkdjAndMx.setDjzt("0");
        csXxDkdjAndMx.setDjrq(new Date());
        csXxDkdjAndMx.setItems(new ArrayList<>());
        return csXxDkdjAndMx;
    }

    @Override
    public Result<String> orderDetailCombineById(String ids, String combineRule, String negaRowNewOrderFlag) {
        if (StringUtils.isEmpty(ids)) {
            throw new JeecgBootException("明细合并，参数不能为空！");
        }
        String[] idArray = ids.split(",");
        if (idArray.length == 0) {
            throw new JeecgBootException("明细合并，参数不能为空！");
        }
        List<String> idList = Arrays.asList(ids.split(","));
        //查询出选择单据的数据
        LambdaQueryWrapper<CsXxDkdj> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CsXxDkdj::getId, idList);
        List<CsXxDkdj> csXxDkdjlist = iCsXxDkdjService.list(wrapper);
        //过虑出已开票、开票中的单据
        List<CsXxDkdj> filterList = csXxDkdjlist.stream().filter(item -> "1".equals(item.getClfs())).collect(Collectors.toList());
        //开票中、已开票的单据不处理
        if (!filterList.isEmpty()) {
            throw new JeecgBootException("选择的单据包括已经合并过的单据");
        }
        try {
            //默认负数行生成新单
            String tmpNegativeRowNewOrderFlag = negaRowNewOrderFlag;
            if (StringUtils.isEmpty(tmpNegativeRowNewOrderFlag)) {
                tmpNegativeRowNewOrderFlag = StringConstant.STR_1;
            }

            List<String> newIdList = new ArrayList<>();
            //默认合并规则
            String strCombineRuleType = combineRule;
            if (StringUtils.isEmpty(strCombineRuleType)) {
                // 默认 "spmc,ggxh,jldw,tax"
                strCombineRuleType = FPUtil.ORDER_DETAIL_DEFAULT_COMBINE_RULE;
            }

            //遍历单据明细合并
            for (String id : idArray) {
                CsXxDkdjAndMx csXxDkdjAndMx = this.getByid(id);
                if (csXxDkdjAndMx == null) {
                    log.info("ID【" + id + "】未查询到数据");
                    continue;
                }
                //记录老的对象
                CsXxDkdjAndMx oldCsXxDkdjAndMx = new CsXxDkdjAndMx();
                BeanUtils.copyProperties(csXxDkdjAndMx, oldCsXxDkdjAndMx);

                List<CsXxDkdjAndMx> newOrderlist = this.detailCombineHandle(csXxDkdjAndMx, strCombineRuleType);
                if (newOrderlist.isEmpty()) {
                    throw new JeecgBootException("合并处理后，未生成新的合并单数据");
                }

                CsXxDkdjAndMx newcsXxDkdjAndMx = newOrderlist.get(0);
                newIdList.add(newcsXxDkdjAndMx.getId());

                //新申请单主表明细表数据保存
                this.newOrderSave(newcsXxDkdjAndMx);

                //更新原来的主表 单据状态为 无效
                LambdaUpdateWrapper<CsXxDkdj> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(CsXxDkdj::getId, oldCsXxDkdjAndMx.getId());
                updateWrapper.set(CsXxDkdj::getDjzt, "1");
                updateWrapper.set(CsXxDkdj::getClfs, "3");//设置原先的单据为被合并单据
                iCsXxDkdjService.update(updateWrapper);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }
        return null;
    }

    @Override
    public Result<String> orderCombineCancel(String id) {
        if(StringUtils.isBlank(id)){
            throw new JeecgBootException("撤销合并，参数不能为空");
        }
        //根据id 查询当前的单据信息
        CsXxDkdj csXxDkdj = iCsXxDkdjService.getById(id);
        if(csXxDkdj == null) throw new JeecgBootException("未查询到当前单据信息");
        if(!"1".equals(csXxDkdj.getClfs())) throw new JeecgBootException("当前单据不是合并单据，无法撤销");
        //当前的单据明细信息
        List<CsXxDkdjmx> CsXxDkdjmxlist = iCsXxDkdjmxService.lambdaQuery().eq(CsXxDkdjmx::getFromid, id).list();

        //1 找到原来的主信息、明细信息 更改状态

        //根据xdjzj 找到 ydjzj
        List<String> xdjzj = CsXxDkdjmxlist.stream().map(CsXxDkdjmx::getId).collect(Collectors.toList());
        List<CsXxDjclmxDo> xdjlist = iCsXxDjclmxService.lambdaQuery().in(CsXxDjclmxDo::getXdjzj, xdjzj).list();
        List<String> ydjzj = xdjlist.stream().map(CsXxDjclmxDo::getYdjzj).collect(Collectors.toList());
        List<CsXxDkdjmx> ydjlist = iCsXxDkdjmxService.lambdaQuery().in(CsXxDkdjmx::getId, ydjzj).list();
        if(ydjlist.isEmpty()) return Result.error("未查询到原单据信息");
        //原单据id 可能有多条
        List<String> ydjids = ydjlist.stream().map(CsXxDkdjmx::getFromid).distinct().collect(Collectors.toList());
        //更改状态&还原处理方式
        LambdaUpdateWrapper<CsXxDkdj> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(CsXxDkdj::getId, ydjids);
        updateWrapper.set(CsXxDkdj::getDjzt, "0");
        updateWrapper.set(CsXxDkdj::getClfs, "0");
        iCsXxDkdjService.update(updateWrapper);

        //2 找到现在的主信息、明细信息 删除
        iCsXxDkdjService.delMain(id);

        //3 删除单据处理表信息
        //单据处理表的主键id
        String djclid = xdjlist.get(0).getFromid();
        iCsXxDjclService.removeById(djclid);
        //删除明细
        iCsXxDjclmxService.removeBatchByIds(xdjlist);

        return Result.OK("撤销成功！");
    }

    @Override
    public Result<String> orderSplitCancel(String id) {
        if(StringUtils.isBlank(id)){
            throw new JeecgBootException("撤销拆分，参数不能为空");
        }
        //这个id是拆分后形成的多条单据中的某一条 单据的id
        //根据id找到当前选择的单据主信息
        CsXxDkdj csXxDkdj = iCsXxDkdjService.getById(id);
        if(csXxDkdj == null) throw new JeecgBootException("未查询到当前单据信息");
        if(!"2".equals(csXxDkdj.getClfs())) throw new JeecgBootException("当前单据不是拆分单据，无法撤销");
        //当前的单据明细信息
        List<CsXxDkdjmx> CsXxDkdjmxlist = iCsXxDkdjmxService.lambdaQuery().eq(CsXxDkdjmx::getFromid, id).list();
        //得到xdjzj  目的是找到 所有的 ydjzj
        List<String> xdjzj = CsXxDkdjmxlist.stream().map(CsXxDkdjmx::getId).collect(Collectors.toList());
        //单据处理明细表  xdjzj的list 应该只有一条记录 因为是拆分后的
        List<CsXxDjclmxDo> xdjlist = iCsXxDjclmxService.lambdaQuery().in(CsXxDjclmxDo::getXdjzj, xdjzj).list();
        //得到formid
        List<String> formid = xdjlist.stream().map(CsXxDjclmxDo::getFromid).distinct().collect(Collectors.toList());
        //得到ydjids
        List<CsXxDjclmxDo> ydjzjs = iCsXxDjclmxService.lambdaQuery().in(CsXxDjclmxDo::getFromid, formid).list();
        List<String> ydjzj = ydjzjs.stream().map(CsXxDjclmxDo::getYdjzj).distinct().collect(Collectors.toList());
        //得到原单据明细
        List<CsXxDkdjmx> ydjlist = iCsXxDkdjmxService.lambdaQuery().in(CsXxDkdjmx::getId, ydjzj).list();
        if(ydjlist.isEmpty()) return Result.error("未查询到原单据信息");
        //原单据id 可能有多条
        List<String> ydjids = ydjlist.stream().map(CsXxDkdjmx::getFromid).distinct().collect(Collectors.toList());
        //更改状态&还原处理方式
        LambdaUpdateWrapper<CsXxDkdj> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(CsXxDkdj::getId, ydjids);
        updateWrapper.set(CsXxDkdj::getDjzt, "0");
        updateWrapper.set(CsXxDkdj::getClfs, "0");
        iCsXxDkdjService.update(updateWrapper);

        //2 找到现在的主信息、明细信息 删除
        //得到现在所有的 单据主键
        List<String> xdjzjs = ydjzjs.stream().map(CsXxDjclmxDo::getXdjzj).distinct().collect(Collectors.toList());
        List<CsXxDkdjmx> list = iCsXxDkdjmxService.lambdaQuery().in(CsXxDkdjmx::getId, xdjzjs).list();
        List<String> formids = list.stream().map(CsXxDkdjmx::getFromid).distinct().collect(Collectors.toList());
        for (String s : formids) {
            iCsXxDkdjService.delMain(s);
        }

        //3 删除单据处理表信息
        String djclid = ydjzjs.get(0).getFromid();
        iCsXxDjclService.removeById(djclid);
        //删除明细
        iCsXxDjclmxService.removeBatchByIds(ydjzjs);

        return Result.OK("撤销成功！");
    }

    private void newOrderSave(CsXxDkdjAndMx csXxDkdjAndMx) {
        //明细数据保存
        for (CsXxDkdjmx item : csXxDkdjAndMx.getItems()) {
            iCsXxDkdjmxService.save(item);
        }
        //主表信息保存
        iCsXxDkdjService.save(csXxDkdjAndMx);
    }


    /**
     * 单据明细合并处理
     *
     * @param csXxDkdjAndMx
     * @param combineRuleType
     * @return
     */
    public List<CsXxDkdjAndMx> detailCombineHandle(CsXxDkdjAndMx csXxDkdjAndMx, String combineRuleType) {
        //单据处理表 主表插入
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        Integer tenant_id = user.getLoginTenantId();
        String company_id = user.getCompanyId();
        String sys_org_code = user.getOrgCode();

        //单据处理表 数据保存
        String djclId = IdWorker.getIdStr();
        CsXxDjclDo csXxDjclDo = new CsXxDjclDo();
        csXxDjclDo.setId(djclId);
        csXxDjclDo.setTenantId(tenant_id);
        csXxDjclDo.setCompanyId(company_id);
        csXxDjclDo.setSysOrgCode(sys_org_code);
        csXxDjclDo.setCllx("1");
        csXxDjclDo.setHblx("mx");
        iCsXxDjclService.save(csXxDjclDo);


        //合并后的新申请单列表
        List<CsXxDkdjAndMx> newOrderlist = new ArrayList<>();
        List<CsXxDkdjmx> orderDetailList = csXxDkdjAndMx.getItems();

        //纠正明细税率为小数点、去除税率、含税单价、不含税单价尾部的零(1、百分比转小数位;2.合并前小数位不一致导致合并不到一行上,例:2600,2600.0)
        this.correctDetailTaxAndDecimal(orderDetailList);

        //实例化合并后的新单据对象
        CsXxDkdjAndMx newOrder = this.copyNewOrder(csXxDkdjAndMx, "1");
        //20231018 yangzheng 改为不重新生成ywdjbh
        //String newywDjbh = IdWorker.getIdStr();
        //newOrder.setYwdjbh(newywDjbh);

        //合并规则
        List<String> groupParam = Arrays.asList(combineRuleType.split(","));
        //对明细进行合并分组，按合并规则进行KEY，value方式处理,注意：折扣行与被折扣行不参加分组处理，处理完后将折扣行与被折扣行添加到合并后的集合中
        Map<String, List<CsXxDkdjmx>> listByGroup = this.getListByGroup(groupParam, orderDetailList, null);

        //根据合并规则明细的值分组遍历
        listByGroup.forEach((key, detailListValue) -> {
            //复制第一行的数据为明细行的主数据
            CsXxDkdjmx sourceDetailEntity = detailListValue.get(0);
            CsXxDkdjmx targetDetailEntity = new CsXxDkdjmx();
            BeanUtils.copyProperties(sourceDetailEntity, targetDetailEntity);
            targetDetailEntity.setFromid(newOrder.getId());
            targetDetailEntity.setYwdjbh(newOrder.getYwdjbh());
            String xdjzj = IdWorker.getIdStr();
            targetDetailEntity.setId(xdjzj);

            //合并规则允许不同单价进行合并时，需要重新计算含税单价，不含税单价
            if (combineRuleType.indexOf("hsdj") == -1 && StringUtils.isNotEmpty(targetDetailEntity.getSpsl() + "")) {
                BigDecimal tmpHsdj = InvoiceCalcUtil.calcPrice(targetDetailEntity.getHsje(), targetDetailEntity.getSpsl());
                targetDetailEntity.setHsdj(tmpHsdj);
                BigDecimal tmpBHsdj = InvoiceCalcUtil.calcPrice(targetDetailEntity.getBhsje(), targetDetailEntity.getSpsl());
                targetDetailEntity.setBhsdj(tmpBHsdj);
            }

            //初始化明细行变量
            String taxStr = targetDetailEntity.getTax().toString();
            BigDecimal spslTotal = BigDecimal.ZERO;
            BigDecimal hsdjTotal = targetDetailEntity.getHsdj();
            BigDecimal bhsdjTotal = targetDetailEntity.getBhsdj();
            BigDecimal hsjeTotal = BigDecimal.ZERO;
            BigDecimal bhsjeTotal = BigDecimal.ZERO;
            BigDecimal seTotal = BigDecimal.ZERO;

            //计算合并行的总金额、数量
            for (CsXxDkdjmx itemEntity : detailListValue) {
                String ydjzj = itemEntity.getId();

                //当合并项仅有一条，且当前行为非合并行时，使用原明细行的行号
                if (detailListValue.size() == NumberConstant.NUM_1) {
                    targetDetailEntity.setMxhh(itemEntity.getMxhh());
                }
                hsjeTotal = hsjeTotal.add(itemEntity.getHsje());
                bhsjeTotal = bhsjeTotal.add(itemEntity.getBhsje());
                //数量有值时
                if (StringUtils.isNotEmpty(itemEntity.getSpsl() + "")) {
                    spslTotal = spslTotal.add(itemEntity.getSpsl());
                }

                //单据处理明细表处理
                CsXxDjclmxDo csXxDjclmxDo = new CsXxDjclmxDo();
                csXxDjclmxDo.setId(IdWorker.getIdStr());
                csXxDjclmxDo.setCompanyId(company_id);
                csXxDjclmxDo.setTenantId(tenant_id);
                csXxDjclmxDo.setSysOrgCode(sys_org_code);
                csXxDjclmxDo.setFromid(djclId);
                csXxDjclmxDo.setYdjzj(ydjzj);
                csXxDjclmxDo.setXdjzj(xdjzj);
                iCsXxDjclmxService.save(csXxDjclmxDo);
            }

            BigDecimal tax = BigDecimal.ZERO;
            if (StringUtils.isNotEmpty(taxStr)) {
                tax = new BigDecimal(taxStr);
            }

            //税率为0时不含税金额=含税金额
            if (tax.compareTo(BigDecimal.ZERO) == 0) {
                bhsjeTotal = hsjeTotal;
            } else {
                //不含税金额计算
                bhsjeTotal = InvoiceCalcUtil.calcNoTaxAmount(hsjeTotal, tax);
            }
            //税额计算
            seTotal = hsjeTotal.subtract(bhsjeTotal);

            //计算含税单价:原始合并项有多条时，需要计算一下金额、数量、单价;仅一条时，金额、数量、单价使用原始数据
            if (detailListValue.size() > 1) {
                //如果有数量了，单价计算
                if (spslTotal.compareTo(BigDecimal.ZERO) != 0) {
                    //当数量变量后，含税单价重新计算；如果不需要计算可以通过传入参数来处理
                    hsdjTotal = InvoiceCalcUtil.calcPrice(hsjeTotal, spslTotal);
                    bhsdjTotal = InvoiceCalcUtil.calcPrice(bhsjeTotal, spslTotal);
                }
            } else {
                //todo:仅一条时，金额、数量、单价使用原始数据,暂不处理，如果有特殊需求了可以在这里实现
            }

            //重新给当前明细行的相关金额赋值
            targetDetailEntity.setHsje(hsjeTotal);
            targetDetailEntity.setBhsje(bhsjeTotal);
            targetDetailEntity.setTaxje(seTotal);
            //判断数量!=0
            if (spslTotal.compareTo(BigDecimal.ZERO) != 0) {
                targetDetailEntity.setSpsl(spslTotal);
                targetDetailEntity.setHsdj(hsdjTotal);
                targetDetailEntity.setBhsdj(bhsdjTotal);
            } else {
                targetDetailEntity.setSpsl(null);
                targetDetailEntity.setHsdj(null);
                targetDetailEntity.setBhsdj(null);
            }
            targetDetailEntity.setFphxz(StringConstant.STR_0);
            //判断当前行的明细金额是否为0，如果为0不添加
            if (hsjeTotal.compareTo(BigDecimal.ZERO) != 0) {
                newOrder.getItems().add(targetDetailEntity);
            }
        });

        //向下为合并后新单据的数据处理
        //对新单据的明细行处理
        List<CsXxDkdjmx> newOrderItemList = newOrder.getItems();
        BigDecimal hsjeTmp = BigDecimal.ZERO;
        BigDecimal bhsjeTmp = BigDecimal.ZERO;

        //新单据明细行序号的处理
        Map<String, String> useableTaxMap = new HashMap<>();
        for (int i = 0; i < newOrderItemList.size(); i++) {
            CsXxDkdjmx csXxDkdjmx = newOrderItemList.get(i);
            csXxDkdjmx.setMxhh(i + 1);
            hsjeTmp = hsjeTmp.add(csXxDkdjmx.getHsje());
            bhsjeTmp = bhsjeTmp.add(csXxDkdjmx.getBhsje());

            String tmpTaxKey = csXxDkdjmx.getTax().toString();
            useableTaxMap.put(tmpTaxKey, tmpTaxKey);
        }
        newOrder.setHjje(bhsjeTmp);
        newOrder.setHjse(hsjeTmp.subtract(bhsjeTmp));
        newOrderlist.add(newOrder);
        return newOrderlist;
    }

    private Map<String, List<CsXxDkdjmx>> getListByGroup(List<String> groupParam, List<CsXxDkdjmx> detaiItem, BigDecimal orderTaxAmount) {
        Map<String, List<CsXxDkdjmx>> groupMap = new LinkedHashMap<>();
        for (int i = 0; i < detaiItem.size(); i++) {
            CsXxDkdjmx detailItemEntity = detaiItem.get(i);

            //折扣行与被折扣行不参加合并，排除不处理
            if (StringConstant.STR_1.equals(detailItemEntity.getFphxz()) || StringConstant.STR_2.equals(detailItemEntity.getFphxz())) {
                continue;
            }

            //组装当前合并属性的值
            String paramStr = "";
            for (int m = 0; m < groupParam.size(); m++) {
                //根据属性名称获取对应属性的值
                Object fieldValue = BeanUtil.getFieldValue(detailItemEntity, groupParam.get(m));
                paramStr += StringUtilsExt.getString(fieldValue);
            }

            //判断合并的值是否存在
            if (groupMap.get(paramStr) != null) {
                //存在
                List<CsXxDkdjmx> tempList = groupMap.get(paramStr);
                tempList.add(detailItemEntity);
            } else {
                //不存在
                List<CsXxDkdjmx> tempList = new ArrayList<>();
                tempList.add(detailItemEntity);
                groupMap.put(paramStr, tempList);
            }
        }
        return groupMap;
    }

    /**
     * 纠正明细税率为小数点、去除税率、含税单价、不含税单价尾部的零，明细合同时，税率、含税单价项合并时，可能由于税率小数点问题导致合并不到一起（例：0.13与0.1300000）
     *
     * @param detailList
     */
    public void correctDetailTaxAndDecimal(List<CsXxDkdjmx> detailList) {
        if (detailList != null) {
            detailList.forEach(item -> {
                String taxStr = item.getTax().toString();
                //税率有值时
                if (StringUtils.isNotEmpty(taxStr)) {
                    BigDecimal tax = new BigDecimal(taxStr);
                    //税率大于1时，转换成小数点
                    if (tax.compareTo(BigDecimal.ONE) >= NumberConstant.NUM_0) {
                        tax = tax.divide(new BigDecimal("100"), NumberConstant.NUM_4, RoundingMode.HALF_UP);
                    }
                    //去尾部0
                    tax = InvoiceCalcUtil.getValueTrimZero(tax);
                    item.setTax(tax);
                }
                BigDecimal tmpVal = item.getHsdj();
                //税率有值时
                if (tmpVal != null) {
                    //去尾部0
                    tmpVal = InvoiceCalcUtil.getValueTrimZero(tmpVal);
                    item.setHsdj(tmpVal);
                }
            });
        }
    }

    public CsXxDkdjAndMx getByid(String id) {
        //取主表数据
        CsXxDkdj csXxDkdj = iCsXxDkdjService.getById(id);
        if (csXxDkdj == null) {
            return null;
        }
        //取明细表数据
        LambdaQueryWrapper<CsXxDkdjmx> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CsXxDkdjmx::getFromid, id);
        List<CsXxDkdjmx> csXxDkdjmx = iCsXxDkdjmxService.list(queryWrapper);

        //合并对象
        CsXxDkdjAndMx csXxDkdjAndMx = new CsXxDkdjAndMx();
        BeanUtils.copyProperties(csXxDkdj, csXxDkdjAndMx);
        csXxDkdjAndMx.setItems(csXxDkdjmx);
        return csXxDkdjAndMx;
    }

    /**
     * 单据拆分
     *
     * @param splitCombineRuleDto
     * @return
     */
    @Override
    public List<String> orderSplitById(DjcfDto splitCombineRuleDto) {
        if (splitCombineRuleDto == null) {
            throw new JeecgBootException("单据拆分，dto参数不能为空！");
        }
        String ids = splitCombineRuleDto.getIds();

        //票面拆分限额
        BigDecimal splitInvoiceAmount = new BigDecimal(splitCombineRuleDto.getMaxInvoiceAmount());

        //数量拆分规则  2 商品数量允许小数拆分（数量没限制要求）  默认
        String quantitySplitRule = "2";

        if (StringUtils.isEmpty(ids)) {
            throw new JeecgBootException("单据拆分，ids参数不能为空！");
        }

        //待拆分的单据ID
        List<String> idList = Arrays.asList(ids.split(","));

        //获取开票限额读取标志  按指定金额拆分
        boolean readInvoiceMaxAmountFlag = true;

        //单据拆分后的新单据ID
        List<String> newOrderIdList = new ArrayList<>();

        try {
            //遍历选择的单据进行拆分处理
            for (String id : idList) {
                CsXxDkdjAndMx csXxDkdjAndMx = this.getByid(id);
                if (csXxDkdjAndMx == null) {
                    throw new JeecgBootException("未查询到拆分的单据,单据ID:" + id);
                }

                //记录老的对象
                CsXxDkdjAndMx oldCsXxDkdjAndMx = new CsXxDkdjAndMx();
                BeanUtils.copyProperties(csXxDkdjAndMx, oldCsXxDkdjAndMx);

                //负数单据不支持拆分
                if (csXxDkdjAndMx.getHjje() == null || csXxDkdjAndMx.getHjje() != null && csXxDkdjAndMx.getHjje().compareTo(BigDecimal.ZERO) <= NumberConstant.NUM_0) {
                    throw new JeecgBootException("不支持负数单据或零金额单据的拆分，单据ID:" + id);
                }

                List<CsXxDkdjAndMx> newOrderList = orderSplitHandle(csXxDkdjAndMx, quantitySplitRule, splitInvoiceAmount, splitCombineRuleDto.getAmountSplitRule());

                //对拆分后的单据进行保存处理
                for (CsXxDkdjAndMx newOrderEntity : newOrderList) {
                    newOrderIdList.add(newOrderEntity.getId());

                    //新拆分的新单据数据添加
                    this.newOrderSave(newOrderEntity);
                }
                //更新原来的主表 单据状态为 无效
                LambdaUpdateWrapper<CsXxDkdj> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(CsXxDkdj::getId, oldCsXxDkdjAndMx.getId());
                updateWrapper.set(CsXxDkdj::getDjzt, "1");
                updateWrapper.set(CsXxDkdj::getClfs, "4");//设置原先的单据为被拆分单据
                iCsXxDkdjService.update(updateWrapper);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }

        return newOrderIdList;
    }

    @Override
    public PageInfo<List<CsXxDkdjmx>> getDetailListBySqdIds(String ids, String pageSize, String page) {
        if (StringUtils.isEmpty(ids)) {
            throw new JeecgBootException("查询明细列表，参数不能为空");
        }
        PageHelper.startPage(Integer.parseInt(page), Integer.parseInt(pageSize));
        String[] idsArray = ids.split(",");
        List<String> idList = Arrays.asList(idsArray);

        LambdaQueryWrapper<CsXxDkdjmx> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(StringUtils.isNotEmpty(ids), CsXxDkdjmx::getFromid, idList);
        List<CsXxDkdjmx> list = iCsXxDkdjmxService.list(queryWrapper);
        PageInfo pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    /**
     * 查看原单
     *
     * @param id
     * @param pageSize
     * @param page
     * @return
     */
    @Override
    public PageInfo<List<CsXxDkdj>> getOriginalList(String id, String pageSize, String page) {
        PageInfo pageInfo = new PageInfo<>(new ArrayList<>());
        if (StringUtils.isEmpty(id)) {
            throw new JeecgBootException("查看原单，id不能为空！");
        }
        //1 在页面上点击查看原单（主表数据）  Id  ---》根据主表数据 查出来 明细数据  xdjzj
        LambdaQueryWrapper<CsXxDkdjmx> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CsXxDkdjmx::getFromid, id);
        List<CsXxDkdjmx> CsXxDkdjmxlist = iCsXxDkdjmxService.list(queryWrapper);
        List<String> xdjzjlist = CsXxDkdjmxlist.stream().map(CsXxDkdjmx::getId).collect(Collectors.toList());
        //2 得到了 xdjzj  查 单据处理明细表  得到  ydjzj
        LambdaQueryWrapper<CsXxDjclmxDo> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(CsXxDjclmxDo::getXdjzj, xdjzjlist);
        List<CsXxDjclmxDo> CsXxDjclmxlist = iCsXxDjclmxService.list(queryWrapper1);
        List<String> ydjzjlist = CsXxDjclmxlist.stream().map(CsXxDjclmxDo::getYdjzj).distinct().collect(Collectors.toList());
        if (ydjzjlist.isEmpty()) {
            return pageInfo;
        }
        //3根据ydjzj   查待开单据明细表 得到formid
        LambdaQueryWrapper<CsXxDkdjmx> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.in(CsXxDkdjmx::getId, ydjzjlist);
        List<CsXxDkdjmx> list = iCsXxDkdjmxService.list(queryWrapper2);
        List<String> formidList = list.stream().map(CsXxDkdjmx::getFromid).distinct().collect(Collectors.toList());
        if (formidList.isEmpty()) {
            return pageInfo;
        }
        //4 根据formid 查待开单主表 得到目标数据
        LambdaQueryWrapper<CsXxDkdj> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.in(CsXxDkdj::getId, formidList);
        List<CsXxDkdj> CsXxDkdjlist = iCsXxDkdjService.list(queryWrapper3);
        pageInfo = new PageInfo<>(CsXxDkdjlist);
        return pageInfo;
    }

    @Override
    public PageInfo<List<CsXxDkdj>> getChildlList(String id, String pageSize, String page) {
        PageInfo pageInfo = new PageInfo<>(new ArrayList<>());
        if (StringUtils.isEmpty(id)) {
            throw new JeecgBootException("查看子单，id不能为空！");
        }
        //1 列表页选择无效单据 点查看子单（主表数据）根据主表数据  查出来明细数据 ydjzj
        LambdaQueryWrapper<CsXxDkdjmx> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CsXxDkdjmx::getFromid, id);
        List<CsXxDkdjmx> CsXxDkdjmxlist = iCsXxDkdjmxService.list(queryWrapper);
        List<String> ydjzjlist = CsXxDkdjmxlist.stream().map(CsXxDkdjmx::getId).collect(Collectors.toList());
        //2 得到了ydjzj 查单据处理明细表  得到 xdjzj
        LambdaQueryWrapper<CsXxDjclmxDo> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(CsXxDjclmxDo::getYdjzj, ydjzjlist);
        List<CsXxDjclmxDo> CsXxDjclmxlist = iCsXxDjclmxService.list(queryWrapper1);
        List<String> xdjzjlist = CsXxDjclmxlist.stream().map(CsXxDjclmxDo::getYdjzj).distinct().collect(Collectors.toList());
        if (xdjzjlist.isEmpty()) {
            return pageInfo;
        }
        //3 根据xdjzj 查待开单据明细表  得到formid
        LambdaQueryWrapper<CsXxDkdjmx> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.in(CsXxDkdjmx::getId, xdjzjlist);
        List<CsXxDkdjmx> list = iCsXxDkdjmxService.list(queryWrapper2);
        List<String> formidList = list.stream().map(CsXxDkdjmx::getFromid).distinct().collect(Collectors.toList());
        if (formidList.isEmpty()) {
            return pageInfo;
        }
        //4 根据formid 查待开单主表 得到目标数据
        LambdaQueryWrapper<CsXxDkdj> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.in(CsXxDkdj::getId, formidList);
        List<CsXxDkdj> CsXxDkdjlist = iCsXxDkdjService.list(queryWrapper3);
        pageInfo = new PageInfo<>(CsXxDkdjlist);
        return pageInfo;
    }

    /**
     * 手工拆分保存
     *
     * @param csXxDkdjAndMx
     * @return
     */
    @Override
    public Result<String> manualSplitOrderSave(CsXxDkdjAndMx csXxDkdjAndMx) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        Integer tenant_id = user.getLoginTenantId();
        String company_id = user.getCompanyId();
        String sys_org_code = user.getOrgCode();
        if (csXxDkdjAndMx == null) {
            throw new JeecgBootException("手工拆分保存，参数不能为空！");
        }
        if (csXxDkdjAndMx.getItems() == null) {
            throw new JeecgBootException("手工拆分保存，明细参数不能为空！");
        }
        //前端页面提交的明细
        List<CsXxDkdjmx> detailList = csXxDkdjAndMx.getItems();
        if (detailList.isEmpty()) {
            throw new JeecgBootException("手工拆分保存，明细内容不能为空！");
        }
        //重新计算不含税金额，税额,因为页面未对它们进行计算
        for (CsXxDkdjmx fpsqdmxPo : detailList) {
            //先赋空值，由工具类重新计算
            fpsqdmxPo.setBhsje(null);
            fpsqdmxPo.setTaxje(null);
            FPUtil.calcItem(fpsqdmxPo, csXxDkdjAndMx.getTspz());
        }

        try {
            //选中的明细  对应的 待开单据 所有的id
            List<String> refIdList = detailList.stream().map(CsXxDkdjmx::getFromid).distinct().collect(Collectors.toList());

            LambdaQueryWrapper<CsXxDkdj> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(CsXxDkdj::getId, refIdList);
            List<CsXxDkdj> dkdjlist = iCsXxDkdjService.list(queryWrapper);
            //关联的所有待开单数据
            List<CsXxDkdjAndMx> refdkdjlist = new ArrayList<>();
            for (CsXxDkdj items : dkdjlist) {
                CsXxDkdjAndMx temp = new CsXxDkdjAndMx();
                BeanUtils.copyProperties(items, temp);
                refdkdjlist.add(temp);
            }

            //关联的所有待开单明细数据
            LambdaQueryWrapper<CsXxDkdjmx> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.in(CsXxDkdjmx::getFromid, refIdList);
            List<CsXxDkdjmx> refSqdmxList = iCsXxDkdjmxService.list(queryWrapper1);

            //从关联的申请单ID中获取第一个申请单数据
            CsXxDkdjAndMx oldDkdjVo = refdkdjlist.get(0);
            //使用第一个申请单的属性 --->  当前的待开单据主表vo
            CsXxDkdjAndMx currDkdjVo = this.generateSplitAfterNewOrder(oldDkdjVo);

            //给代开单据主表 赋值
            this.manualSplitOrderInfoCopy(currDkdjVo, csXxDkdjAndMx);
            //拆分的明细处理 返回单据处理的主键
            String djclId = this.manualSplitDetailHandle(detailList, currDkdjVo, refSqdmxList);
            //20231018 yangzheng 改为不生成新的ywdjbh
            //String newYwdjbh = IdWorker.getIdStr();
            //currDkdjVo.setYwdjbh(newYwdjbh);

            List<CsXxDkdjmx> refNewSqdmxList = new ArrayList<>();
            //从原单据的明细列表中移出新单据关联的明细数据
            for (CsXxDkdjmx detailItem : refSqdmxList) {
                refNewSqdmxList.add(detailItem);
            }
            List<String> idNewList = new ArrayList<>();
            //处理原单据（拆分前的关联单据）的明细、明细原始单据（单据金额、明细序号、明细新ID等）
            for (int j = 0; j < refIdList.size(); j++) {
                String Id = refIdList.get(j);

                //过滤出原单据（拆分前的关联单据）对象
                CsXxDkdjAndMx filterSqdVo = refdkdjlist.stream().filter(item -> item.getId().equals(Id)).findFirst().orElse(null);
                if (filterSqdVo == null) {
                    continue;
                }
                //过滤出原单据（拆分前的关联单据）明细对象(不包括拆分后新单据的明细)列表
                List<CsXxDkdjmx> sqdmxListFilter = refNewSqdmxList.stream().filter(item -> item.getFromid().equals(Id)).collect(Collectors.toList());
                filterSqdVo.setId(IdWorker.getIdStr());
                idNewList.add(filterSqdVo.getId());
                BigDecimal tmpHsjeTotal = BigDecimal.ZERO;
                BigDecimal tmpBhsjeTotal = BigDecimal.ZERO;
                //处理明细的序号、汇总明细的含税金额、不含税金额
                for (int i = 0; i < sqdmxListFilter.size(); i++) {
                    CsXxDkdjmx csXxDkdjmx = sqdmxListFilter.get(i);
                    String ydjzj = csXxDkdjmx.getId();
                    csXxDkdjmx.setMxhh(i + 1);
                    tmpHsjeTotal = tmpHsjeTotal.add(csXxDkdjmx.getHsje());
                    tmpBhsjeTotal = tmpBhsjeTotal.add(csXxDkdjmx.getBhsje());
                    csXxDkdjmx.setFromid(filterSqdVo.getId());
                    //由于原来单据明细没删 所以这里保存剩下的明细时  id需要更换
                    String xdjzj = IdWorker.getIdStr();
                    csXxDkdjmx.setId(xdjzj);

                    //单据处理明细表处理 这里处理的是 拆分过后 原来单据剩下的数据 也是新生成的单据  也需要插入单据处理明细表
                    CsXxDjclmxDo csXxDjclmxDo = new CsXxDjclmxDo();
                    csXxDjclmxDo.setId(IdWorker.getIdStr());
                    csXxDjclmxDo.setCompanyId(company_id);
                    csXxDjclmxDo.setTenantId(tenant_id);
                    csXxDjclmxDo.setSysOrgCode(sys_org_code);
                    csXxDjclmxDo.setFromid(djclId);
                    csXxDjclmxDo.setYdjzj(ydjzj);
                    csXxDjclmxDo.setXdjzj(xdjzj);
                    iCsXxDjclmxService.save(csXxDjclmxDo);
                }
                filterSqdVo.setHjje(tmpBhsjeTotal);
                filterSqdVo.setHjse(tmpHsjeTotal.subtract(tmpBhsjeTotal));
            }

            //拆分后关联原单据(不包含拆分后的新单据)的保存
            this.splitAfterRefOrderSave(idNewList, refdkdjlist, refNewSqdmxList);

            this.newOrderSave(currDkdjVo);

            //更新原来的单据状态为无效
            LambdaUpdateWrapper<CsXxDkdj> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.in(CsXxDkdj::getId, refIdList);
            updateWrapper.set(CsXxDkdj::getDjzt, "1");
            updateWrapper.set(CsXxDkdj::getClfs, "4");//设置原先的单据为被拆分单据
            iCsXxDkdjService.update(updateWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }
        return null;
    }

    @Override
    public void changeInvoiceType(String ids, String fplxdm, String tspz) {
        if ("".equals(ids) || "".equals(fplxdm) || "".equals(tspz)) {
            throw new JeecgBootException("票种变更参数：ids,fplxdm,tspz都不能为空！");
        }
        try {
            String[] idsArray = ids.split(",");
            List<String> idsList = Arrays.asList(idsArray);
            LambdaUpdateWrapper<CsXxDkdj> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.in(CsXxDkdj::getId, idsList);
            updateWrapper.set(StringUtils.isNotEmpty(fplxdm), CsXxDkdj::getFplxdm, fplxdm);
            updateWrapper.set(StringUtils.isNotEmpty(tspz), CsXxDkdj::getTspz, tspz);
            iCsXxDkdjService.update(updateWrapper);
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }
    }

    @Override
    public PreviewQRcodeVo previewQRcode(String id) {
        PreviewQRcodeVo previewQRcodeVo = new PreviewQRcodeVo();
        if (StringUtils.isEmpty(id)) {
            throw new JeecgBootException("生成开票二维码，参数不能为空");
        }
        try {
            String dkdj_ewm_url = sysDictService.queryDictTextByKey("xxparams","dkdj_ewm_url");

            CsXxDkdj csXxDkdj = iCsXxDkdjService.getById(id);
            LambdaQueryWrapper<CsXxDkdjmx> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(CsXxDkdjmx::getFromid, csXxDkdj.getId());
            List<CsXxDkdjmx> CsXxDkdjmxs = iCsXxDkdjmxService.list(queryWrapper);
            previewQRcodeVo.setCsXxDkdj(csXxDkdj);
            previewQRcodeVo.setItems(CsXxDkdjmxs);
            String Url = dkdj_ewm_url + "?ddid=" + csXxDkdj.getId() + "&tenantId=" + csXxDkdj.getTenantId();
            String QRcodeUrl = BarCodeUtils.getImage2Base64String(BarCodeUtils.generateBarcodeWithoutWhite(Url, null));
            previewQRcodeVo.setQRcodeUrl(QRcodeUrl);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }
        return previewQRcodeVo;
    }

    @Override
    public List<IntelligentCodingVo> intelligentCoding(String id) {
        List<IntelligentCodingVo> returnList = new ArrayList<>();
        try {
            //1 根据id 查询需要赋码的明细
            CsXxDkdj csXxDkdj = iCsXxDkdjService.getById(id);
            List<CsXxDkdjmx> list = iCsXxDkdjmxService.lambdaQuery().eq(CsXxDkdjmx::getFromid, csXxDkdj.getId()).and(i -> {
                i.eq(CsXxDkdjmx::getSpbm, "").or().isNull(CsXxDkdjmx::getSpbm);
            }).list();
            if (list.isEmpty()) {
                throw new JeecgBootException("没有需要赋码的明细！");
            }
            for (int i = 0; i < list.size(); i++) {
                CsXxDkdjmx csXxDkdjmx = list.get(i);
                IntelligentCodingVo intelligentCodingVo = new IntelligentCodingVo();
                intelligentCodingVo.setId(csXxDkdjmx.getId());
                String spmc = csXxDkdjmx.getSpmc();
                intelligentCodingVo.setResult(xxBase.znfm(spmc).getResult());
                intelligentCodingVo.setSpmc(spmc);

                //查询商品表信息
                List<CsXxProduct> products = iCsXxProductService.lambdaQuery().eq(CsXxProduct::getSpmc, spmc)
                        .eq(StringUtils.isNotBlank(csXxDkdjmx.getGgxh()), CsXxProduct::getGgxh, csXxDkdjmx.getGgxh())
                        .eq(StringUtils.isNotBlank(csXxDkdjmx.getJldw()), CsXxProduct::getJldw, csXxDkdjmx.getJldw())
                        .orderByDesc(CsXxProduct::getGgxh).orderByDesc(CsXxProduct::getJldw).list();
                if (!products.isEmpty()) {
                    intelligentCodingVo.setSpid(products.get(0).getId());
                }
                returnList.add(intelligentCodingVo);
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }
        return returnList;
    }

    @Override
    public void saveIntelligentCoding(IntelligentCodingMainDto dto) {
        if (dto == null) {
            throw new JeecgBootException("智能赋码保存，参数不能为空！");
        }
        if (dto.getMxxx().isEmpty()) {
            throw new JeecgBootException("智能赋码保存，参数不能为空！");
        }
        String autosave = dto.getAutosave();
        List<IntelligentCodingDto> dtos = dto.getMxxx();
        try {
            for (IntelligentCodingDto intelligentCodingDto : dtos) {
                CsXxDkdjmx csXxDkdjmx = new CsXxDkdjmx();
                csXxDkdjmx.setId(intelligentCodingDto.getId());
                csXxDkdjmx.setSpbm(intelligentCodingDto.getSsflbm());
                csXxDkdjmx.setSsmc(intelligentCodingDto.getSsflmc());
                csXxDkdjmx.setLslbs(intelligentCodingDto.getLslbs());
                csXxDkdjmx.setZzstsgl(intelligentCodingDto.getZzstsgl());
                csXxDkdjmx.setYhzcbs(intelligentCodingDto.getYhzcbs());
                iCsXxDkdjmxService.updateById(csXxDkdjmx);

                if ("1".equals(autosave)) {
                    CsXxProduct csXxProduct = new CsXxProduct();
                    csXxProduct.setId(intelligentCodingDto.getSpid());
                    csXxProduct.setLslbs(intelligentCodingDto.getLslbs());
                    csXxProduct.setZzstsgl(intelligentCodingDto.getZzstsgl());
                    csXxProduct.setYhzcbs(intelligentCodingDto.getYhzcbs());
                    iCsXxProductService.updateById(csXxProduct);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }

    }


    private void splitAfterRefOrderSave(List<String> idNewList, List<CsXxDkdjAndMx> refSqdList, List<CsXxDkdjmx> refNewSqdmxList) {
        //原单据(不包含拆分后的新单据)数据保存
        if (idNewList.isEmpty()) {
            return;
        }
        for (String Id : idNewList) {
            //处理剩余申请单的数据
            CsXxDkdjAndMx filterSqdVo = refSqdList.stream().filter(item -> item.getId().equals(Id)).findFirst().orElse(null);
            //单据明细数据
            List<CsXxDkdjmx> sqdmxListFilter = refNewSqdmxList.stream().filter(item -> item.getFromid().equals(Id)).collect(Collectors.toList());
            if (filterSqdVo != null) {
                Map<String, String> djbhMap = Maps.newHashMap();
                //单据明细保存
                for (CsXxDkdjmx item : sqdmxListFilter) {
                    iCsXxDkdjmxService.save(item);
                    djbhMap.put(item.getYwdjbh(), item.getYwdjbh());
                }
                iCsXxDkdjService.save(filterSqdVo);
            }
        }
    }

    private String manualSplitDetailHandle(List<CsXxDkdjmx> detailList, CsXxDkdjAndMx currDkdjVo, List<CsXxDkdjmx> refDetailList) {
        //单据处理表 主表插入
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        Integer tenant_id = user.getLoginTenantId();
        String company_id = user.getCompanyId();
        String sys_org_code = user.getOrgCode();

        //单据处理表 数据保存
        String djclId = IdWorker.getIdStr();
        CsXxDjclDo csXxDjclDo = new CsXxDjclDo();
        csXxDjclDo.setId(djclId);
        csXxDjclDo.setTenantId(tenant_id);
        csXxDjclDo.setCompanyId(company_id);
        csXxDjclDo.setSysOrgCode(sys_org_code);
        csXxDjclDo.setCllx("2");//拆分
        csXxDjclDo.setCflx("sg");//手工拆分
        iCsXxDjclService.save(csXxDjclDo);


        BigDecimal hsjeTotal = BigDecimal.ZERO;
        BigDecimal bhsjeTotal = BigDecimal.ZERO;
        //明细遍历拆分处理
        for (int i = 0; i < detailList.size(); i++) {
            CsXxDkdjmx csXxDkdjmx = detailList.get(i);

            String ydjzj = csXxDkdjmx.getId();

            //当前明细行数据源
            CsXxDkdjmx currNewDetailPo = new CsXxDkdjmx();
            BeanUtil.copyProperties(csXxDkdjmx, currNewDetailPo);
            String xdjzj = IdWorker.getIdStr();
            currNewDetailPo.setId(xdjzj);
            currNewDetailPo.setMxhh(i + 1);
            currNewDetailPo.setFromid(currDkdjVo.getId());

            //税率
            BigDecimal currRowTax = currNewDetailPo.getTax();
            BigDecimal currRowTmpTax = BigDecimal.ZERO;
            if (currRowTax != null) {
                currRowTmpTax = currRowTax;
            }
            //变量定义
            BigDecimal currRowHsje = currNewDetailPo.getHsje();
            BigDecimal currRowSpsl = currNewDetailPo.getSpsl();
            //去尾部0
            if (currRowSpsl != null) {
                currNewDetailPo.setSpsl(InvoiceCalcUtil.getValueTrimZero(currRowSpsl));
            }

            //判断原明细行的金额与拆分后新单据的明细行金额比较是否相等，不相等需要处理，查询原明细行的
            CsXxDkdjmx refFpsqdmxPo = refDetailList.stream().filter(item -> item.getId().equals(csXxDkdjmx.getId())).findFirst().orElse(null);
            //异常情况
            if (refFpsqdmxPo == null) {
                continue;
            }
            //新单据关联的原始单据处理
            // 新单据明细行的金额没有拆分情况，直接从原明细行中移出，否则修改
            if (refFpsqdmxPo != null && refFpsqdmxPo.getHsje().compareTo(currRowHsje) == 0) {
                //从原单明细行中移除
                refDetailList.remove(refFpsqdmxPo);
            } else {
                //原单明细行进行了拆分情况:
                //第一步：计算原单明细剩余金额(含税金额、不含税金额、税额、数量等)
                //第二步：计算原单明细关联的原始单明细
                //重新计算 原单据明细行的相关金额
                //明细行剩余含税金额
                BigDecimal tmpSurplusRowHsje = refFpsqdmxPo.getHsje().subtract(currRowHsje);
                //明细行剩余不含税金额
                BigDecimal tmpSurplusRowBhsje = InvoiceCalcUtil.calcNoTaxAmount(tmpSurplusRowHsje, currRowTmpTax);
                //明细行剩余不税额
                BigDecimal tmpSurplusRowSe = tmpSurplusRowHsje.subtract(tmpSurplusRowBhsje);
                BigDecimal tmpRowHsdj = currNewDetailPo.getHsdj();
                BigDecimal tmpRowBhsdj = currNewDetailPo.getBhsdj();
                //明细行剩余数量
                BigDecimal tmpSurplusRowSpslStr = refFpsqdmxPo.getSpsl();
                BigDecimal tmpSurplusRowSpsl = BigDecimal.ZERO;
                //剩余数量=原数量-拆分数量(todo:可能会因为重新计算导致数量为负数的情况，需要验证),也可以根据不含税单价重新计算数量
                if (tmpSurplusRowSpslStr != null) {
                    tmpSurplusRowSpsl = InvoiceCalcUtil.getValueTrimZero(tmpSurplusRowSpslStr.subtract(currRowSpsl));
                    tmpSurplusRowSpslStr = tmpSurplusRowSpsl;
                }
                //原单剩余的明细行处理
                refFpsqdmxPo.setHsje(tmpSurplusRowHsje);
                refFpsqdmxPo.setBhsje(tmpSurplusRowBhsje);
                refFpsqdmxPo.setTaxje(tmpSurplusRowSe);
                refFpsqdmxPo.setSpsl(tmpSurplusRowSpslStr);
                refFpsqdmxPo.setHsdj(tmpRowHsdj);
                refFpsqdmxPo.setBhsdj(tmpRowBhsdj);
            }
            hsjeTotal = hsjeTotal.add(currNewDetailPo.getHsje());
            bhsjeTotal = bhsjeTotal.add(currNewDetailPo.getBhsje());
            //明细行对象添加到新拆分的当前单据中
            currDkdjVo.getItems().add(currNewDetailPo);

            //单据处理明细表处理
            CsXxDjclmxDo csXxDjclmxDo = new CsXxDjclmxDo();
            csXxDjclmxDo.setId(IdWorker.getIdStr());
            csXxDjclmxDo.setCompanyId(company_id);
            csXxDjclmxDo.setTenantId(tenant_id);
            csXxDjclmxDo.setSysOrgCode(sys_org_code);
            csXxDjclmxDo.setFromid(djclId);
            csXxDjclmxDo.setYdjzj(ydjzj);
            csXxDjclmxDo.setXdjzj(xdjzj);
            iCsXxDjclmxService.save(csXxDjclmxDo);
        }
        currDkdjVo.setHjje(bhsjeTotal);
        currDkdjVo.setHjse(hsjeTotal.subtract(bhsjeTotal));
        return djclId;
    }

    private void manualSplitOrderInfoCopy(CsXxDkdjAndMx currFpsqdVo, CsXxDkdjAndMx fpsqdVo) {
        currFpsqdVo.setFplxdm(fpsqdVo.getFplxdm());
        currFpsqdVo.setTspz(fpsqdVo.getTspz());
        currFpsqdVo.setZsfs(fpsqdVo.getZsfs());
        currFpsqdVo.setBz(fpsqdVo.getBz());
        currFpsqdVo.setKhmc(fpsqdVo.getKhmc());
        currFpsqdVo.setKhsh(fpsqdVo.getKhsh());
        currFpsqdVo.setKhdz(fpsqdVo.getKhdz());
        currFpsqdVo.setKhdh(fpsqdVo.getKhdh());
        currFpsqdVo.setKhlxyx(fpsqdVo.getKhlxyx());
        currFpsqdVo.setKhlxfs(fpsqdVo.getKhlxfs());
        if (StringUtils.isNotEmpty(currFpsqdVo.getKhlxyx())) {
            currFpsqdVo.setKhlxfs(currFpsqdVo.getKhlxyx());
        } else {
            currFpsqdVo.setKhlxfs(currFpsqdVo.getKhlxfs());
        }
        currFpsqdVo.setKhdz(fpsqdVo.getKhdz());
        currFpsqdVo.setKhdh(fpsqdVo.getKhdh());
        currFpsqdVo.setKhyh(fpsqdVo.getKhyh());
        currFpsqdVo.setKhzh(fpsqdVo.getKhzh());
    }

    /**
     * 单据拆分处理
     * 如果该单据包括折扣行，则折扣行添加到最后一个单据上，如果最后一个单据的单据金额加上折扣行大于最大票面金额时，折扣行的明细单据放到一个新单据中
     *
     * @param csXxDkdjAndMx
     * @param quantitySplitRule 数量拆分规则
     * @param maxInvoiceAmount  拆分票面最大金额
     * @param amountSplitRule   金额拆分规则  1-含税 2-不含税
     * @return
     */
    private List<CsXxDkdjAndMx> orderSplitHandle(CsXxDkdjAndMx csXxDkdjAndMx, String quantitySplitRule, BigDecimal maxInvoiceAmount, String amountSplitRule) {
        //单据处理表 主表插入
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        Integer tenant_id = user.getLoginTenantId();
        String company_id = user.getCompanyId();
        String sys_org_code = user.getOrgCode();

        //单据处理表 数据保存  单据拆分业务
        String djclId = IdWorker.getIdStr();
        CsXxDjclDo csXxDjclDo = new CsXxDjclDo();
        csXxDjclDo.setId(djclId);
        csXxDjclDo.setTenantId(tenant_id);
        csXxDjclDo.setCompanyId(company_id);
        csXxDjclDo.setSysOrgCode(sys_org_code);
        csXxDjclDo.setCllx("2");
        csXxDjclDo.setCflx("dj");//单据拆分
        iCsXxDjclService.save(csXxDjclDo);

        List<CsXxDkdjAndMx> newOrderlist = new ArrayList<>();
        //含税金额
        BigDecimal originAmount = csXxDkdjAndMx.getHjje().add(csXxDkdjAndMx.getHjse());
        //单据明细
        List<CsXxDkdjmx> oldDetailList = csXxDkdjAndMx.getItems();

        if (maxInvoiceAmount != null) {
            //赋值按含税金额还是不含税金额进行判断
            //含税金额
            BigDecimal je = csXxDkdjAndMx.getHjje().add(csXxDkdjAndMx.getHjse());
            //不含税
            if (StringConstant.STR_2.equals(amountSplitRule)) {
                //不含税金额
                je = csXxDkdjAndMx.getHjje();
            }
            if (je.compareTo(maxInvoiceAmount) <= NumberConstant.NUM_0) {
                //无需处理的拆分单据处理
                csXxDkdjAndMx = this.noHandleOrderSplit(csXxDkdjAndMx);
                newOrderlist.add(csXxDkdjAndMx);
                return newOrderlist;
            }
        }

        //分离出正常行与折扣行和被折扣行的明细
        //单据明细（正常行明细集合）
        List<CsXxDkdjmx> normalRowDetailList = new ArrayList<>();
        //折扣单据明细集合
        List<CsXxDkdjmx> discountRowDetailList = new ArrayList<>();
        for (CsXxDkdjmx item : oldDetailList) {
            if (StringConstant.STR_0.equals(item.getFphxz())) {
                //正常行
                normalRowDetailList.add(item);
            } else {
                //折扣行或被折扣行
                discountRowDetailList.add(item);
            }
        }

        CsXxDkdjAndMx currCsXxDkdjAndMx = this.generateSplitAfterNewOrder(csXxDkdjAndMx);
        //20231018 yangzheng 改为不生成新的业务单据编号
        //String newYwdjbh = IdWorker.getIdStr();
        //currCsXxDkdjAndMx.setYwdjbh(newYwdjbh);

        //当前单据的变量定义
        BigDecimal currOrderHsje = BigDecimal.ZERO;
        BigDecimal currOrderBhsje = BigDecimal.ZERO;
        BigDecimal currOrderSe = BigDecimal.ZERO;
        int currMxhh = NumberConstant.NUM_1;

        //当前单据添加到拆分后的单据列表中
        newOrderlist.add(currCsXxDkdjAndMx);

        //明细遍历（正常行）拆分处理
        for (int i = 0; i < normalRowDetailList.size(); i++) {
            CsXxDkdjmx csXxDkdjmx = normalRowDetailList.get(i);

            String ydjzj = csXxDkdjmx.getId();

            //复制并生成新的当前原明细行对象，用于计算或保存当前行剩余的数据
            CsXxDkdjmx currOriginDetailVo = new CsXxDkdjmx();
            BeanUtil.copyProperties(csXxDkdjmx, currOriginDetailVo);

            //税率
            String currRowTax = currOriginDetailVo.getTax().toString();
            BigDecimal currRowTmpTax = BigDecimal.ZERO;
            if (StringUtils.isNotEmpty(currRowTax)) {
                currRowTmpTax = new BigDecimal(currRowTax);
            }

            //明细行是否循环拆分新单据
            boolean isLoopSplitOrderFlag = true;
            //是否需要拆分生成新单
            boolean generatenNewOrderFlag = false;
            while (isLoopSplitOrderFlag) {
                isLoopSplitOrderFlag = false;
                generatenNewOrderFlag = false;

                BigDecimal currRowHsje = currOriginDetailVo.getHsje();
                BigDecimal currRowBhsje = currOriginDetailVo.getBhsje();
                BigDecimal currRowSe = currOriginDetailVo.getTaxje();
                BigDecimal currRowHsdj = currOriginDetailVo.getHsdj();
                BigDecimal currRowBhsdj = currOriginDetailVo.getBhsdj();
                String currRowSpsl = Convert.toStr(currOriginDetailVo.getSpsl(), "1");

                //判断当前单据金额是否大于票面金额,如果大于则需要对当前行进行拆分//考虑明细行未拆分大于面额，明细行合并后大于面额、有折扣行的情况处理
                if (maxInvoiceAmount != null) {
                    //赋值按含税金额还是不含税金额进行判断
                    BigDecimal currOrderTmpJe = BigDecimal.ZERO;
                    //不含税
                    if (StringConstant.STR_2.equals(amountSplitRule)) {
                        currOrderTmpJe = currOrderBhsje.add(currOriginDetailVo.getBhsje());
                    } else {
                        //含税金额
                        currOrderTmpJe = currOrderHsje.add(currOriginDetailVo.getHsje());
                    }

                    //加上当前行后，票面金额是否大于当前单据金额,对当前行进行拆分相关逻辑处理
                    if (currOrderTmpJe.compareTo(maxInvoiceAmount) > NumberConstant.NUM_0) {
                        isLoopSplitOrderFlag = true;
                        generatenNewOrderFlag = true;

                        //拆分后当前单据最大剩余明细行的含税金额；票面金额-当前单据已有的金额=当前单据剩余明细行金额
                        //不含税
                        if (StringConstant.STR_2.equals(amountSplitRule)) {
                            currRowBhsje = maxInvoiceAmount.subtract(currOrderBhsje);
                            currRowSe = InvoiceCalcUtil.getValueTrimZero(currRowBhsje.multiply(currRowTmpTax), NumberConstant.NUM_2);
                            currRowHsje = currRowBhsje.add(currRowSe);
                        } else {
                            //含税金额
                            currRowHsje = maxInvoiceAmount.subtract(currOrderHsje);
                            currRowBhsje = InvoiceCalcUtil.calcNoTaxAmount(currRowHsje, currRowTmpTax);
                            currRowSe = currRowHsje.subtract(currRowBhsje);
                        }

                        //计算数量
                        if (currRowBhsdj != null && currRowBhsdj.compareTo(BigDecimal.ZERO) != NumberConstant.NUM_0) {
                            currRowSpsl = String.valueOf(InvoiceCalcUtil.calcQuantity(currRowBhsje, currRowBhsdj));
                        }

                        //计算当前明细行剩余的金额相关数据,如果当前明细行为非合并标志，则默认为剩余的原始数据；
                        currOriginDetailVo.setHsje(currOriginDetailVo.getHsje().subtract(currRowHsje));
                        currOriginDetailVo.setBhsje(InvoiceCalcUtil.calcNoTaxAmount(currOriginDetailVo.getHsje(), currRowTmpTax));
                        currOriginDetailVo.setTaxje(currOriginDetailVo.getHsje().subtract(currOriginDetailVo.getBhsje()));
                        if (currOriginDetailVo.getBhsdj() != null && currOriginDetailVo.getBhsdj().compareTo(BigDecimal.ZERO) != NumberConstant.NUM_0) {
                            currOriginDetailVo.setSpsl(InvoiceCalcUtil.calcQuantity(currOriginDetailVo.getBhsje(), currOriginDetailVo.getBhsdj()));
                        }
                    } else {
                        //加上当前行正数是票面金额，生成新单据，不对当前行明细进行循环
                        if (currOrderTmpJe.compareTo(maxInvoiceAmount) == NumberConstant.NUM_0) {
                            //生成新单据
                            generatenNewOrderFlag = true;
                            //标记成循环拆分
                            isLoopSplitOrderFlag = false;
                        }
                    }
                }

                //拆分后新的明细行对象
                CsXxDkdjmx newDetailVo = this.copyNewOrderDetail(csXxDkdjmx, currCsXxDkdjAndMx.getId());
                newDetailVo.setMxhh(currMxhh);
                newDetailVo.setHsje(currRowHsje);
                newDetailVo.setBhsje(currRowBhsje);
                newDetailVo.setTaxje(currRowSe);
                newDetailVo.setHsdj(currRowHsdj);
                newDetailVo.setBhsdj(currRowBhsdj);
                //明细的业务单据编号更新
                newDetailVo.setYwdjbh(currCsXxDkdjAndMx.getYwdjbh());
                newDetailVo.setSpsl(new BigDecimal(currRowSpsl));

                //当前明细行的金额累加
                currOrderHsje = currOrderHsje.add(newDetailVo.getHsje());
                currOrderBhsje = currOrderBhsje.add(newDetailVo.getBhsje());
                currOrderSe = currOrderSe.add(newDetailVo.getTaxje());
                //明细行添加到新单据中
                currCsXxDkdjAndMx.getItems().add(newDetailVo);

                //明细序号+1
                currMxhh = currMxhh + 1;

                //生成新单据
                if (isLoopSplitOrderFlag || generatenNewOrderFlag) {
                    //单据处理明细表处理
                    CsXxDjclmxDo csXxDjclmxDo = new CsXxDjclmxDo();
                    csXxDjclmxDo.setId(IdWorker.getIdStr());
                    csXxDjclmxDo.setCompanyId(company_id);
                    csXxDjclmxDo.setTenantId(tenant_id);
                    csXxDjclmxDo.setSysOrgCode(sys_org_code);
                    csXxDjclmxDo.setFromid(djclId);
                    csXxDjclmxDo.setYdjzj(ydjzj);
                    csXxDjclmxDo.setXdjzj(newDetailVo.getId());
                    iCsXxDjclmxService.save(csXxDjclmxDo);

                    //上一单据的处理
                    currCsXxDkdjAndMx.setHjse(currOrderHsje.subtract(currOrderBhsje));
                    currCsXxDkdjAndMx.setHjje(currOrderBhsje);

                    //生成拆分后的新单据
                    currCsXxDkdjAndMx = this.generateSplitAfterNewOrder(csXxDkdjAndMx);

                    currOrderHsje = BigDecimal.ZERO;
                    currOrderBhsje = BigDecimal.ZERO;
                    currOrderSe = BigDecimal.ZERO;
                    currMxhh = NumberConstant.NUM_1;

                    //currCsXxDkdjAndMx.setYwdjbh(IdWorker.getIdStr());
                    //当前单据添加到拆分后的单据列表中
                    newOrderlist.add(currCsXxDkdjAndMx);
                } else {
                    //不生成新单据  拆分后的最后一条记录处理
                    //单据处理明细表处理
                    CsXxDjclmxDo csXxDjclmxDo = new CsXxDjclmxDo();
                    csXxDjclmxDo.setId(IdWorker.getIdStr());
                    csXxDjclmxDo.setCompanyId(company_id);
                    csXxDjclmxDo.setTenantId(tenant_id);
                    csXxDjclmxDo.setSysOrgCode(sys_org_code);
                    csXxDjclmxDo.setFromid(djclId);
                    csXxDjclmxDo.setYdjzj(ydjzj);
                    csXxDjclmxDo.setXdjzj(newDetailVo.getId());
                    iCsXxDjclmxService.save(csXxDjclmxDo);
                }
            }
        }

        //对最后一个单据的金额、行数进行处理
        CsXxDkdjAndMx lastFpsqdVo = newOrderlist.get(newOrderlist.size() - 1);

        //将折扣行追加到最后一个单据上
        if (!discountRowDetailList.isEmpty()) {
            //折扣行生成一个新单
        } else {
            lastFpsqdVo.setHjse(currOrderHsje.subtract(currOrderBhsje));
            lastFpsqdVo.setHjje(currOrderBhsje);
        }
        newOrderlist.removeIf(next -> next.getItems().isEmpty());
        return newOrderlist;
    }


    private CsXxDkdjmx copyNewOrderDetail(CsXxDkdjmx source, String id) {
        CsXxDkdjmx csXxDkdjmx = new CsXxDkdjmx();
        BeanUtils.copyProperties(source, csXxDkdjmx);
        csXxDkdjmx.setFromid(id);
        csXxDkdjmx.setId(IdWorker.getIdStr());
        return csXxDkdjmx;
    }

    private CsXxDkdjAndMx generateSplitAfterNewOrder(CsXxDkdjAndMx csXxDkdjAndMx) {
        CsXxDkdjAndMx csXxDkdjAndMx1 = this.copyNewOrder(csXxDkdjAndMx, "2");
        csXxDkdjAndMx1.setHjje(null);
        csXxDkdjAndMx1.setHjse(null);
        return csXxDkdjAndMx1;
    }


    /**
     * 不需要处理的单据拆分处理
     *
     * @param csXxDkdjAndMx
     * @return
     */
    private CsXxDkdjAndMx noHandleOrderSplit(CsXxDkdjAndMx csXxDkdjAndMx) {
        String newId = IdWorker.getIdStr();
        csXxDkdjAndMx.setId(newId);
        //明细行的申请单ID,明细ID生成新的
        for (CsXxDkdjmx itemDetail : csXxDkdjAndMx.getItems()) {
            itemDetail.setFromid(newId);
            itemDetail.setId(IdWorker.getIdStr());
        }
        return csXxDkdjAndMx;
    }

}
